# -*- coding: utf-8 -*-

import httplib
import socket

class _AEConnection:
	""" This class is the main connection to the google
		app engine server. No originDB specific implementation
		is here, it should all be in the other files in this module.
		Using this object you should only make method calls and the
		methods with _ prepending them are private.
		Here is where we keep track of the session
	"""

	def __init__(self, host=""):
		""" Host is the name of the host we are connecting to.
			The actual connection is created in this method
		"""
		self.host = host
		self._conn = None
		self._sID = ''
		self._errorCallback = None
		
		#	if we were provided with a host
		if host:
			#	connect using our class function
			self.connect(host)


	def connect(self, host=""):
		""" Connect to the host provided or reconnect to old host
		"""
		if self._conn:
			self._conn.close()
		
		if not host:
			if self.host:
				host = self.host
			else:
				return

		self._conn = httplib.HTTPConnection(host)
		
		try:
			self._conn.connect()
		except socket.error as err_val:
			err_msg = 'Error ' + str(err_val.errno) + ': ' + err_val.strerror;
			if self._errorCallback:
				self._errorCallback(err_msg)
			raise DatabaseError()


	def setSID(self, sID):
		self._sID = sID


	def userLoggedIn(self):
		if self._sID:
			return True
		else:
			return False


	def _makeURL(self, action, params):
		""" Make a url that our GAE server can understand
		"""
		params['sID'] = self._sID
		
		url = "/" + action + "?"
		for key in params:
			url += str(key)+'='+str(params[key])+'&'

		return url


	def getAction(self, action, params):
		""" -action is the action you want to perform on the server
			(i.e. get, login, search)
			-params are the params that action requires.
			-return value is the body of the response from the server
			this is normally some yaml.
		"""
		self._conn.request("GET", self._makeURL(action, params))

		resp = self._conn.getresponse()

		if resp.status != httplib.OK:
			if self._errorCallback:
				self._errorCallback(resp.reason)
			raise DatabaseError(resp.reason)

		body = resp.read()

		return body


	def postAction(self, action, body, params):
		""" -action is the action you want to perform on the server
			(i.e. get, login, search)
			-params are the params that action requires.
			-return value is the body of the response from the server
			this is normally some yaml.
		"""
		self._conn.request("POST", self._makeURL(action, params), body)

		resp = self._conn.getresponse()

		if resp.status != httplib.OK:
			if self._errorCallback:
				self._errorCallback(resp.reason)
			raise DatabaseError(resp.reason)

		body = resp.read()

		return body
		
	
	def setErrorHandler(self, func):
		self._errorCallback = func

class DatabaseError(Exception):

	def __init__(self, value):
		self.value = value
		print value

	def __str__(self):
		return str(value)

dbHandle = _AEConnection()
